package com.ruoyi.pack.service.impl;

import java.util.Date;
import java.util.List;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pack.domain.PackLocator;
import com.ruoyi.pack.domain.PackContainer;
import com.ruoyi.pack.domain.PackContainerOperationLog;
import com.ruoyi.pack.mapper.PackLocatorMapper;
import com.ruoyi.pack.mapper.PackContainerMapper;
import com.ruoyi.pack.service.IPackLocatorService;
import com.ruoyi.pack.service.IPackContainerOperationLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 定位器Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Service
public class PackLocatorServiceImpl implements IPackLocatorService 
{
    @Autowired
    private PackLocatorMapper packLocatorMapper;
    
    @Autowired
    private PackContainerMapper packContainerMapper;
    
    @Autowired
    private IPackContainerOperationLogService packContainerOperationLogService;

    /**
     * 查询定位器
     * 
     * @param locatorId 定位器主键
     * @return 定位器
     */
    @Override
    public PackLocator selectPackLocatorByLocatorId(Long locatorId)
    {
        return packLocatorMapper.selectPackLocatorByLocatorId(locatorId);
    }

    /**
     * 查询定位器列表
     * 
     * @param packLocator 定位器
     * @return 定位器
     */
    @Override
    public List<PackLocator> selectPackLocatorList(PackLocator packLocator)
    {
        return packLocatorMapper.selectPackLocatorList(packLocator);
    }

    /**
     * 新增定位器
     * 
     * @param packLocator 定位器
     * @return 结果
     */
    @Override
    public int insertPackLocator(PackLocator packLocator)
    {
        // 设置默认状态
        if (StringUtils.isEmpty(packLocator.getLocatorStatus()))
        {
            packLocator.setLocatorStatus("1"); // 默认正常
        }
        packLocator.setCreateTime(DateUtils.getNowDate());
        return packLocatorMapper.insertPackLocator(packLocator);
    }

    /**
     * 修改定位器
     * 
     * @param packLocator 定位器
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePackLocator(PackLocator packLocator)
    {
        // 1. 获取原始定位器信息
        PackLocator oldLocator = packLocatorMapper.selectPackLocatorByLocatorId(packLocator.getLocatorId());
        if (oldLocator == null) {
            throw new ServiceException("定位器不存在");
        }
        
        Long oldContainerId = oldLocator.getContainerId();
        Long newContainerId = packLocator.getContainerId();
        
        // 2. 执行正常的更新操作
        packLocator.setUpdateTime(DateUtils.getNowDate());
        int result = packLocatorMapper.updatePackLocator(packLocator);
        
        // 3. 处理器具绑定关系变化的日志记录
        if (result > 0) {
            handleContainerBindingChange(oldContainerId, newContainerId, packLocator);
        }
        
        return result;
    }

    /**
     * 批量删除定位器
     * 
     * @param locatorIds 需要删除的定位器主键
     * @return 结果
     */
    @Override
    public int deletePackLocatorByLocatorIds(Long[] locatorIds)
    {
        return packLocatorMapper.deletePackLocatorByLocatorIds(locatorIds);
    }

    /**
     * 删除定位器信息
     * 
     * @param locatorId 定位器主键
     * @return 结果
     */
    @Override
    public int deletePackLocatorByLocatorId(Long locatorId)
    {
        return packLocatorMapper.deletePackLocatorByLocatorId(locatorId);
    }

    /**
     * 根据定位器编码查询定位器
     * 
     * @param locatorCode 定位器编码
     * @return 定位器
     */
    @Override
    public PackLocator selectPackLocatorByLocatorCode(String locatorCode)
    {
        return packLocatorMapper.selectPackLocatorByLocatorCode(locatorCode);
    }

    /**
     * 更新定位器状态
     * 
     * @param locatorId 定位器ID
     * @param locatorStatus 定位器状态
     * @param batteryLevel 电池电量
     * @param signalStrength 信号强度
     * @return 结果
     */
    @Override
    public int updateLocatorStatus(Long locatorId, String locatorStatus, Long batteryLevel, Long signalStrength)
    {
        return packLocatorMapper.updateLocatorStatus(locatorId, locatorStatus, batteryLevel, signalStrength);
    }

    /**
     * 查询未绑定运单的定位器
     * 
     * @return 定位器集合
     */
    @Override
    public List<PackLocator> selectUnboundLocators()
    {
        return packLocatorMapper.selectUnboundLocators();
    }

    /**
     * 查询已绑定运单的定位器
     * 
     * @return 定位器集合
     */
    @Override
    public List<PackLocator> selectBoundLocators()
    {
        return packLocatorMapper.selectBoundLocators();
    }

    /**
     * 校验定位器编码唯一性
     * 
     * @param locatorCode 定位器编码
     * @return 结果 true-唯一 false-不唯一
     */
    @Override
    public boolean checkLocatorCodeUnique(String locatorCode)
    {
        PackLocator locator = packLocatorMapper.selectPackLocatorByLocatorCode(locatorCode);
        return locator == null;
    }

    /**
     * 校验定位器是否可以绑定
     * 
     * @param locatorId 定位器ID
     * @return 结果 true-可以绑定 false-不可以绑定
     */
    @Override
    public boolean checkLocatorCanBind(Long locatorId)
    {
        PackLocator locator = packLocatorMapper.selectPackLocatorByLocatorId(locatorId);
        if (locator == null)
        {
            return false;
        }
        
        // 检查定位器状态是否正常
        if (!"1".equals(locator.getLocatorStatus()))
        {
            return false;
        }
        
        // 检查定位器是否已被绑定（通过查询是否有器具绑定了此定位器）
        List<PackLocator> boundLocators = selectBoundLocators();
        for (PackLocator boundLocator : boundLocators)
        {
            if (boundLocator.getLocatorId().equals(locatorId))
            {
                return false;
            }
        }
        
        return true;
    }

    /**
     * 校验定位器状态是否正常
     * 
     * @param locatorId 定位器ID
     * @return 结果 true-正常 false-异常
     */
    @Override
    public boolean checkLocatorStatusNormal(Long locatorId)
    {
        PackLocator locator = packLocatorMapper.selectPackLocatorByLocatorId(locatorId);
        if (locator == null)
        {
            return false;
        }
        
        return "1".equals(locator.getLocatorStatus());
    }

    /**
     * 导入定位器数据
     * 
     * @param locatorList 定位器数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importLocator(List<PackLocator> locatorList, Boolean isUpdateSupport, String operName)
    {
        if (StringUtils.isNull(locatorList) || locatorList.size() == 0)
        {
            throw new ServiceException("导入定位器数据不能为空！");
        }
        
        int successNum = 0;
        int failureNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        
        for (PackLocator locator : locatorList)
        {
            try
            {
                // 验证是否存在这个定位器
                PackLocator existLocator = packLocatorMapper.selectPackLocatorByLocatorCode(locator.getLocatorCode());
                if (StringUtils.isNull(existLocator))
                {
                    // 新增定位器
                    locator.setCreateBy(operName);
                    locator.setCreateTime(DateUtils.getNowDate());
                    if (StringUtils.isEmpty(locator.getLocatorStatus()))
                    {
                        locator.setLocatorStatus("1"); // 默认正常状态
                    }
                    this.insertPackLocator(locator);
                    successNum++;
                }
                else if (isUpdateSupport)
                {
                    // 更新定位器
                    locator.setLocatorId(existLocator.getLocatorId());
                    locator.setUpdateBy(operName);
                    locator.setUpdateTime(DateUtils.getNowDate());
                    this.updatePackLocator(locator);
                    successNum++;
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、定位器编码 " + locator.getLocatorCode() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、定位器编码 " + locator.getLocatorCode() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            return "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：";
        }
    }
    
    /**
     * 处理器具绑定关系变化的日志记录
     * 
     * @param oldContainerId 原绑定器具ID
     * @param newContainerId 新绑定器具ID
     * @param locator 定位器信息
     */
    private void handleContainerBindingChange(Long oldContainerId, Long newContainerId, PackLocator locator) {
        try {
            // 场景1：原来未绑定 → 现在绑定
            if (oldContainerId == null && newContainerId != null) {
                recordContainerOperationLog(newContainerId, "2", "绑定定位器", locator.getLocatorCode());
            }
            // 场景2：原来绑定 → 现在未绑定
            else if (oldContainerId != null && newContainerId == null) {
                recordContainerOperationLog(oldContainerId, "3", "解绑定位器", locator.getLocatorCode());
            }
            // 场景3：原来绑定A → 现在绑定B
            else if (oldContainerId != null && newContainerId != null && !oldContainerId.equals(newContainerId)) {
                recordContainerOperationLog(oldContainerId, "3", "解绑定位器", locator.getLocatorCode());
                recordContainerOperationLog(newContainerId, "2", "绑定定位器", locator.getLocatorCode());
            }
            // 场景4和5：无变化，不记录日志
        } catch (Exception e) {
            // 日志记录失败不影响主要业务逻辑，只记录错误日志
            System.err.println("记录器具操作日志失败: " + e.getMessage());
        }
    }
    
    /**
     * 记录器具操作日志
     * 
     * @param containerId 器具ID
     * @param operationType 操作类型
     * @param operationDesc 操作描述
     * @param locatorCode 定位器编码
     */
    private void recordContainerOperationLog(Long containerId, String operationType, String operationDesc, String locatorCode) {
        try {
            PackContainerOperationLog log = new PackContainerOperationLog();
            log.setContainerId(containerId);
            log.setOperationType(operationType);
            log.setOperationDetail(operationDesc + "：" + locatorCode);
            log.setOperationTime(new Date());
            
            // 获取器具信息，设置所在库房ID
            try {
                PackContainer container = packContainerMapper.selectPackContainerByContainerId(containerId);
                if (container != null && container.getCurrentWarehouseId() != null) {
                    log.setWarehouseId(container.getCurrentWarehouseId());
                }
            } catch (Exception e) {
                // 如果获取器具信息失败，不设置库房ID
                System.err.println("获取器具库房信息失败: " + e.getMessage());
            }
            
            // 获取当前操作用户信息
            try {
                Long userId = SecurityUtils.getUserId();
                log.setOperatorId(userId);
            } catch (Exception e) {
                // 如果获取用户信息失败，设置为null
                log.setOperatorId(null);
            }
            
            try {
                String username = SecurityUtils.getUsername();
                log.setCreateBy(username);
            } catch (Exception e) {
                // 如果获取用户名失败，设置为默认值
                log.setCreateBy("system");
            }
            
            packContainerOperationLogService.insertPackContainerOperationLog(log);
        } catch (Exception e) {
            // 日志记录失败不影响主要业务逻辑，只记录错误日志
            System.err.println("记录器具操作日志失败: " + e.getMessage());
        }
    }
} 